package com.ly.mp.busicen.rule.instrumentation;

import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import com.ly.mp.busicen.rule.flow.IDataVolume;
import com.ly.mp.busicen.rule.flow.IFlowContext;
import com.ly.mp.busicen.rule.flow.IFlowResult;
import com.ly.mp.busicen.rule.flow.IFlowResultCtn;
import com.ly.mp.busicen.rule.flow.IFlowVolume;
import com.ly.mp.busicen.rule.flow.action.IAction;
import com.ly.mp.busicen.rule.flow.action.IActionResult;
import com.ly.mp.busicen.rule.flow.filter.FlowFilter;
import com.ly.mp.busicen.rule.flow.filter.FlowInvocation;
import com.ly.mp.busicen.rule.flow.filter.FlowResult;

// 把注册的 探测器, 一起执行, 相当于一个组合类combination
public class FlowInstrumentationManager implements IFlowInstrumentation {
	
	private static final Logger log = LoggerFactory.getLogger(FlowInstrumentationManager.class);

	@Autowired
	FlowInstrumentationContainer flowInstrumentationContainer;
	
	
	@Override
	public void beginFlow(String flow, String brand, Map<String, Object> data,String rid) {
		flowInstrumentationContainer.getInstrumentations().forEach(m->{
			invokeInstrumentation(()->m.beginFlow(flow, brand, data, rid));
		});
		
	}

	@Override
	public void endBuildContext(IFlowContext context) {
		flowInstrumentationContainer.getInstrumentations().forEach(m->{
			invokeInstrumentation(()->m.endBuildContext(context));
		});		
	}

	@Override
	public void beginActionInvoke(IAction action, IFlowContext context, IFlowResultCtn result) {
		flowInstrumentationContainer.getInstrumentations().forEach(m->{
			invokeInstrumentation(()->m.beginActionInvoke(action, context, result));
		});	
		
	}

	@Override
	public void endActionInvoke(IAction action, IFlowContext context, IFlowResultCtn result, IFlowResult flowResult) {
		flowInstrumentationContainer.getInstrumentations().forEach(m->{
			invokeInstrumentation(()->m.endActionInvoke(action, context, result, flowResult));
		});	
	}

	@Override
	public void beginFilter(FlowFilter flowFilter, FlowInvocation invocation) {
		flowInstrumentationContainer.getInstrumentations().forEach(m->{
			invokeInstrumentation(()->m.beginFilter(flowFilter, invocation));
		});			
	}
	
	@Override
	public void endFilter(FlowFilter flowFilter, FlowInvocation invocation, FlowResult filterResult) {
		flowInstrumentationContainer.getInstrumentations().forEach(m->{
			invokeInstrumentation(()->m.endFilter(flowFilter, invocation, filterResult));
		});
		
	}

	@Override
	public void endFlow(IFlowResultCtn result) {
		flowInstrumentationContainer.getInstrumentations().forEach(m->{
			invokeInstrumentation(()->m.endFlow(result));
		});	
	}

	@Override
	public void beginActionExecute(IAction action, IDataVolume dataVolume, IFlowVolume flowVolume) {
		flowInstrumentationContainer.getInstrumentations().forEach(m->{
			invokeInstrumentation(()->m.beginActionExecute(action, dataVolume, flowVolume));
		});			
	}

	@Override
	public void endActionExecute(IAction action, IDataVolume dataVolume, IFlowVolume flowVolume,
			IActionResult actionResult) {
		flowInstrumentationContainer.getInstrumentations().forEach(m->{
			invokeInstrumentation(()->m.endActionExecute(action, dataVolume, flowVolume, actionResult));
		});			
	}
	
	
	@FunctionalInterface
	public static interface FlowInstruSuppler{
		void get();
	}
	
	public void invokeInstrumentation(FlowInstruSuppler suppler) {
		try {
			suppler.get();
		}catch (FlowInstrumentationException e) {			
			log.error("规则引擎探测器执行异常，停止执行",e);
			if (e.getCause() instanceof RuntimeException) {
				throw (RuntimeException)e.getCause();
			}
			throw new RuntimeException(e.getCause());
		} catch (Exception e) {
			log.error("规则引擎探测器执行异常，继续执行",e);
		}		
	}

	@Override
	public String label() {
		return "";
	}

	

}
